/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2008 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Web;
using System.Threading;
using System.Collections.Generic;

using Gtk;
using Glade;
using Pango;

using Anculus.Core;
using Anculus.Gui;

using Galaxium.Core;
using Galaxium.Client;
using Galaxium.Protocol;
using Galaxium.Protocol.Gui;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;

namespace Galaxium.Protocol.GaduGadu.GtkGui
{
	public class GaduChatWidget : BasicChatWidget
	{
		private ContactListView _contactList = null;
		
		// Common properties that we can include.
		public override bool ShowActionToolbar
		{
			get { return (Conversation.PrimaryContact as GaduContact).ShowActionToolbar; }
			set { (Conversation.PrimaryContact as GaduContact).ShowActionToolbar = value; if (value) _window.Toolbar.ShowAll(); else _window.Toolbar.Visible = false; }
		}
		
		public override bool ShowInputToolbar
		{
			get { return (Conversation.PrimaryContact as GaduContact).ShowInputToolbar; }
			set { (Conversation.PrimaryContact as GaduContact).ShowInputToolbar = value; if (value) _entryToolbar.ShowAll(); else _entryToolbar.Visible = false; }
		}
		
		public override bool ShowAccountImage
		{
			get { return (Conversation.PrimaryContact as GaduContact).ShowAccountImage; }
			set { (Conversation.PrimaryContact as GaduContact).ShowAccountImage = value; if (value) _leftInputBox.ShowAll(); else _leftInputBox.Visible = false; }
		}
		
		public override bool ShowContactImage
		{
			get { return (Conversation.PrimaryContact as GaduContact).ShowContactImage; }
			set { (Conversation.PrimaryContact as GaduContact).ShowContactImage = value; if (value) _rightInputBox.ShowAll(); else _rightInputBox.Visible = false; }
		}
		
		public override bool ShowPersonalMessage
		{
			get { return (Conversation.PrimaryContact as GaduContact).ShowPersonalMessage; }
			set { (Conversation.PrimaryContact as GaduContact).ShowPersonalMessage = value; if (value) _identificationBox.ShowAll(); else _identificationBox.Visible = false; }
		}
		
		public override bool ShowTimestamps
		{
			get { return (Conversation.PrimaryContact as GaduContact).ShowTimestamps; }
			set { (Conversation.PrimaryContact as GaduContact).ShowTimestamps = value; }
		}
		
		public override bool UseDefaultView
		{
			get { return (Conversation.PrimaryContact as GaduContact).UseDefaultView; }
			set { (Conversation.PrimaryContact as GaduContact).UseDefaultView = value; }
		}
		
		public override bool EnableLogging
		{
			get { return Conversation.PrimaryContact.EnableLogging; }
			set { Conversation.PrimaryContact.EnableLogging = value; }
		}
		
		public override bool EnableSounds
		{
			get { return (Conversation.PrimaryContact as GaduContact).EnableSounds; }
			set { (Conversation.PrimaryContact as GaduContact).EnableSounds = value; }
		}
		
		public override bool UseDefaultSettings
		{
			get { return (Conversation.PrimaryContact as GaduContact).UseDefaultSettings; }
			set { (Conversation.PrimaryContact as GaduContact).UseDefaultSettings = value; }
		}
		
		internal GaduChatWidget (IContainerWindow<Widget> window, IConversation conversation) : base (window, conversation)
		{
			// Here is where we can connect all the events that need to be mapped for the chat window to work.
			_conversation.Established += ConversationEstablishedEvent;
			_conversation.Closed += ConversationClosedEvent;
			_conversation.ContactJoined += ConversationContactJoinedEvent;
			_conversation.ContactLeft += ConversationContactLeftEvent;
			_conversation.AllContactsLeft += ConversationAllContactsLeftEvent;
			_conversation.MessageReceived += ConversationMessageReceivedEvent;
			
			// The following are not available in Gadu yet.
			
			//_conversation.NudgeReceived += ConversationNudgeReceivedEvent;
			//_conversation.TypingReceived += ConversationContactTypingEvent;
			//_conversation.MessageSendFailed += ConversationMessageSendFailed;
			//_conversation.CapabilitiesChanged += ConversationCapabilitiesChanged;
			//(_conversation as GaduCoversation).ActionMessageReceived -= ConversationActionMessageReceived;
			
			_conversation.Session.Account.DisplayImageChange += AccountDisplayImageChange;
			
			//_typingTimer.Elapsed += new System.Timers.ElapsedEventHandler(TypingTimerElapsed);
			//_ownerTimer.Elapsed += new System.Timers.ElapsedEventHandler(OwnerTimerElapsed);
			_conversation.Active = true;
		}
		
		public override void Initialize ()
		{
			// You must always call this first before doing anything
			base.Initialize ();
			
			_contactList = new ContactListView (Conversation);
			_contactList.Manager = new ListContactTreeManager ();
			
			SetChatWidget (ChatWidgetPositions.RightDisplayPane, _contactList);
			
			AdjustForContacts ();
			
			// Load up the conversation history logs.
			
			IConversationLog log = Conversation.ConversationLog;
			int n = _logging_config.GetInt("HistorySize", 5);
			
			_historyComplete = false;
			
			if (ConversationLogUtility.EnableLogging && n > 0)
			{
				List<ConversationLogEntry> entries = new List<ConversationLogEntry> ();
				entries.AddRange (log.GetNLastEntries (n));
				
				//Anculus.Core.Log.Debug ("Found {0} log entries", entries.Count);
				
				if (entries.Count > 0)
				{
						// Wrap this in a try...catch so that we can never stop the ListenerReady property
						// being set to true
						
						try
						{
							foreach (ConversationLogEntry entry in entries)
							{
								//Anculus.Core.Log.Debug ("Entry, {0}: '{1}'", entry.IsEvent ? "event" : "message", entry.Message);
								
								if (entry.IsEvent)
								{
									//TODO: Some way to show these are history items
									//TODO: The message display never gets the real timestamp
									
									_message_display.AddEvent (entry.Message);
									continue;
								}
								
								//Anculus.Core.Log.Debug ("UID:  {0} ({1})", entry.UniqueIdentifier, (_conversation.Session as GaduSession).FindEntity (entry.UniqueIdentifier));
								//Anculus.Core.Log.Debug ("Name: {0}", entry.DisplayName);
								
								//if (string.IsNullOrEmpty (entry.UniqueIdentifier))
								//	continue;
								
								IMessage message = new Message (MessageFlag.Message | MessageFlag.History, (_conversation.Session as GaduSession).FindEntity (entry.UniqueIdentifier), null, entry.TimeStamp);
								message.SetMarkup (entry.Message, null);
							
								_message_display.AddMessage (message);
							}
						}
						catch (Exception ex)
						{
							Anculus.Core.Log.Error (ex, "Error displaying history");
						}
						
						_historyComplete = true;
						
						//(_conversation as GaduConversation).ListenerReady = true;
				}
				else
				{
					_historyComplete = true;
					
					_nativeWidget.SizeAllocated += SizeAllocated;
				}
			}
			else
			{
				// We aren't ready until the GdkWindows for the widgets are created
				// otherwise WinkDisplay hits a null reference trying to find it's
				// position and size
				// When the size is allocated, we know we're ready
				_nativeWidget.SizeAllocated += SizeAllocated;
				
				_historyComplete = true;
			}
			
			foreach (IMessage msg in (_conversation as GaduConversation).IncomingQueue)
			{
				ProcessIncomingMessage (msg);
			}
			
			(_conversation as GaduConversation).IncomingQueue.Clear();
			
			_nativeWidget.Show ();
		}
		
		void SizeAllocated (object sender, EventArgs args)
		{
			//(_conversation as GaduConversation).ListenerReady = true;
			_nativeWidget.SizeAllocated -= SizeAllocated;
		}
		
		public override void SwitchTo ()
		{
			MenuUtility.FillToolBar ("/Galaxium/Gui/GG/ContainerWindow/Toolbar", new DefaultExtensionContext (this), _window.Toolbar as Toolbar);
			MenuUtility.FillMenuBar ("/Galaxium/Gui/GG/ContainerWindow/Menu", new DefaultExtensionContext (this), _window.Menubar as MenuBar);
			MenuUtility.FillToolBar ("/Galaxium/Gui/GG/ContainerWindow/InputToolbar", new DefaultExtensionContext (this), _entryToolbar);
		}
		
		public override void SwitchFrom ()
		{
		}
		
		public override void Destroy ()
		{
			// Make sure we stop all timers.
			//lock (_ownerTimer)
			//	_ownerTimer.Stop();
			//lock (_typingTimer)
			//	_typingTimer.Stop();
			
			//_conversation.ListenerReady = false;
			
			_conversation.Active = false;
			
			_conversation.Established -= ConversationEstablishedEvent;
			_conversation.Closed -= ConversationClosedEvent;
			_conversation.ContactJoined -= ConversationContactJoinedEvent;
			_conversation.ContactLeft -= ConversationContactLeftEvent;
			_conversation.AllContactsLeft -= ConversationAllContactsLeftEvent;
			_conversation.MessageReceived -= ConversationMessageReceivedEvent;
			//_conversation.InkReceived -= ConversationInkReceivedEvent;
			//_conversation.NudgeReceived -= ConversationNudgeReceivedEvent;
			//_conversation.TypingReceived -= ConversationContactTypingEvent;
			//_conversation.WinkReceived -= ConversationWinkReceived;
			//_conversation.VoiceClipReceived -= ConversationVoiceClipReceived;
			//_conversation.MessageSendFailed -= ConversationMessageSendFailed;
			//_conversation.WebcamInviteReceived -= ConversationWebcamInviteReceived;
			//_conversation.CapabilitiesChanged -= ConversationCapabilitiesChanged;
		}
		
		/*private void TypingTimerElapsed(object o, EventArgs oArgs)
		{
			_imagePosition++;
			_imageTime--;
			
			if (_imagePosition > 4)
				_imagePosition = 1;
			
			if (_imageTime < 1)
			{
				_imageRepeat--;
				_imageTime = 10;
				
				if (_imageRepeat < 1)
				{
					lock (_typingTimer)
						_typingTimer.Enabled = false;
					
				
						_activityImage.FromPixbuf = IconUtility.GetIcon("galaxium-typing_blank");
						_statusLabel.Text = "";
					});
				}
				
				return;
			}
			
		
				// Show the image that matches the new count.
				switch (_imagePosition)
				{
					case 1:
						_activityImage.FromPixbuf = IconUtility.GetIcon("galaxium-typing_anim0");
						break;
					
					case 2:
						_activityImage.FromPixbuf = IconUtility.GetIcon("galaxium-typing_anim1");
						break;
					
					case 3:
						_activityImage.FromPixbuf = IconUtility.GetIcon("galaxium-typing_anim2");
						break;
					
					case 4:
						_activityImage.FromPixbuf = IconUtility.GetIcon("galaxium-typing_anim3");
						break;
				}
			});
		}*/
		
		/*private void OwnerTimerElapsed(object o, EventArgs oArgs)
		{
			 (delegate
			{
				int length = _messageEntry.Buffer.Text.Length;
				
				if (length < 1)
				{
					lock (_ownerTimer)
						_ownerTimer.Enabled = false;
				}
				//else
					//_conversation.SendTyping ();
			});
		}*/
		
		[GLib.ConnectBefore	()]
		protected override void MessageEntryKeyRelease (object sender, KeyReleaseEventArgs args)
		{
			Gdk.Key key = args.Event.Key;
			uint state = ((uint)args.Event.State);
			state &= 1101u;
			const uint Normal = 0, Shift = 1, Control = 4, ShiftControl = 5, Alt = 8;
			
			switch (state)
			{
				case Normal:
					if (key == Gdk.Key.BackSpace || key == Gdk.Key.Delete)
						if (_messageEntry.Text.Length < 1)
					{
							//lock (_ownerTimer)
								//_ownerTimer.Enabled = false;
					}
					break;
				case Shift:
					break;
				case Control:
					break;
				case ShiftControl:
					break;
				case Alt:
					break;
				default:
					break;
			}
		}
		
		[GLib.ConnectBefore ()]
		protected override void MessageEntryKeyPress (object sender, KeyPressEventArgs args)
		{
			Gdk.Key key = args.Event.Key;
			uint state = ((uint)args.Event.State);
			state &= 1101u;
			const uint Normal = 0, Shift = 1, Control = 4;//, ShiftControl = 5, Alt = 8;
			
			GaduContact contact = Conversation.PrimaryContact as GaduContact;
			
			if (contact == null)
			{
				Anculus.Core.Log.Error ("There is no primary contact to send messages to in this conversation!");
				return;
			}
			
			switch (state)
			{
				case Normal:
					if (key == Gdk.Key.Return || key == Gdk.Key.KP_Enter)
					{
						if (_messageEntry.Text.Trim().Length < 1)
						{
							args.RetVal = true;
							return;
						}
					
						/*if (!_conversation.CanSendMessage)
						{
							_messageDisplay.AddSystemMessage ("Galaxium is unable to send a message to this contact");
						
							args.RetVal = true;
							return;
						}*/
						
						//GaduTextStyle style = GetStyle ();
						
						IMessage tmessage = new Message (MessageFlag.Message, _conversation.Session.Account, null, DateTime.Now);
						tmessage.SetMarkup (_messageEntry.Text, null);

						ProcessOutgoingMessage (tmessage);
					
						_messageEntry.Clear();
						
						_message_display.AddMessage(tmessage);
					
						//lock (_ownerTimer)
						//	_ownerTimer.Enabled = false;
						
						args.RetVal = true;
						
						return;
					}
					else
					{
						/*lock (_ownerTimer)
						{
							if (_messageEntry.Buffer.Text.Length < 2 && (key == Gdk.Key.BackSpace || key == Gdk.Key.Delete))
								_ownerTimer.Enabled = false;
							else if (key != Gdk.Key.BackSpace && key != Gdk.Key.Delete)
								_ownerTimer.Enabled = true;
						}*/
					}
					break;
				case Shift:
					break;
				case Control:
					break;
				default:
					break;
			}
		}
		
		private void ConversationEstablishedEvent (object sender, ConversationEventArgs args)
		{
			/* (delegate ()
			{
				if (CoreUtility.Debug)
					_messageDisplay.AddSystemMessage("Conversation ["+args.Conversation.UniqueIdentifier+"] started.");
			});*/
		}
		
		private void ConversationClosedEvent (object sender, ConversationEventArgs args)
		{
			/* (delegate ()
			{
				if (CoreUtility.Debug)
					_messageDisplay.AddSystemMessage("Conversation ["+args.Conversation.UniqueIdentifier+"] ended.");
			});*/
		}
		
		void ConversationContactJoinedEvent (object sender, ContactActionEventArgs args)
		{
			AdjustForContacts ();
			
			if (Conversation.ContactCollection.Count > 1)
				_message_display.AddEvent (args.Contact.DisplayIdentifier + " has joined the conversation");
		
			if (args.Contact != Conversation.PrimaryContact)
				AddEventHandlers (args.Contact as GaduContact);
		}
		
		void ConversationContactLeftEvent (object sender, ContactActionEventArgs args)
		{
			AdjustForContacts ();
			
			if (Conversation.ContactCollection.Count > 1)
				_message_display.AddEvent (args.Contact.DisplayIdentifier + " has left the conversation");
		
			if (args.Contact != Conversation.PrimaryContact)
				RemoveEventHandlers (args.Contact as GaduContact);
		}
		
		void AddEventHandlers (GaduContact contact)
		{
			contact.DisplayImageChange += ContactDisplayImageChanged;
			contact.DisplayMessageChange += ContactDisplayMessageChanged;
			contact.DisplayNameChange += ContactDisplayNameChanged;
			contact.PresenceChange += ContactPresenceChanged;
			contact.SupressChange += ContactSupressChanged;
		}
		
		void RemoveEventHandlers (GaduContact contact)
		{
			contact.DisplayImageChange -= ContactDisplayImageChanged;
			contact.DisplayMessageChange -= ContactDisplayMessageChanged;
			contact.DisplayNameChange -= ContactDisplayNameChanged;
			contact.PresenceChange -= ContactPresenceChanged;
			contact.SupressChange -= ContactSupressChanged;
		}
		
		void ConversationAllContactsLeftEvent (object sender, ConversationEventArgs args)
		{
			
		}
		
		private void ConversationMessageReceivedEvent (object sender, MessageEventArgs args)
		{
			Log.Info ("MessageReceived {0}", args.Message.Markup);
			ProcessIncomingMessage (args.Message);
		}
				
		/*private void ConversationNudgeReceivedEvent (object sender, ContactEventArgs args)
		{
		
			_message_display.AddEvent (args.Contact.DisplayIdentifier + " is nudging you to get your attention!");
			
			EmitBecomeActive ();
			
			if (_config.GetBool("WindowShake", true))
				_window.Shake();
		
			SoundSetUtility.Play(Sound.Nudge);
		}*/
		
		/*private void ConversationContactTypingEvent (object sender, ContactEventArgs args)
		{
			/*lock (_typingTimer)
			{
				if (_typingTimer.Enabled != true)
					_imageRepeat = 4;
				
				_typingTimer.Enabled = true;
			}*//*
			
			_status_label.Text = args.Contact.DisplayIdentifier+" is now typing a message...";
			EmitBecomingActive ();
		}*/
		
		private void ContactSupressChanged (object sender, EntityChangeEventArgs<bool> args)
		{
			if ((Conversation.PrimaryContact as GaduContact).SupressImage)
				_contact_image.FadeTo (PixbufUtility.GetScaledPixbuf (IconUtility.GetIcon ("galaxium-displayimage", IconSizes.Huge), 96, 96));
			else
			{
				try
				{
					_contact_image.FadeTo (PixbufUtility.GetScaledPixbuf (new Gdk.Pixbuf(Conversation.PrimaryContact.DisplayImage.ImageBuffer), 96, 96));
				}
				catch
				{
					_contact_image.FadeTo (PixbufUtility.GetScaledPixbuf (IconUtility.GetIcon ("galaxium-displayimage", IconSizes.Huge), 96, 96));
				}
			}
		}
		
		void ContactDisplayNameChanged (object sender, EntityChangeEventArgs<string> args)
		{
			_message_display.AddEvent (args.Old + " has changed their name to: " + args.New);
		}
		
		void ContactDisplayMessageChanged (object sender, EntityChangeEventArgs<string> args)
		{
			GaduContact contact = args.Entity as GaduContact;
			
			GeneratePersonalLabel ();
			if (!string.IsNullOrEmpty (contact.DisplayMessage))
				_personalLabel.Markup = "Message: "+XmlUtility.Encode (contact.UniqueIdentifier) + ": " + XmlUtility.Encode (contact.DisplayMessage);
			else
				_personalLabel.Markup = XmlUtility.Encode (contact.UniqueIdentifier) + ": No personal message.";
		}
		
		void ContactDisplayImageChanged (object sender, EntityChangeEventArgs<IDisplayImage> args)
		{
			GaduContact contact = args.Entity as GaduContact;
			
			if (contact == _conversation.PrimaryContact)
			{
				// If the contact has an image, but we've not yet got the data
				// don't switch the image, this will be called again once the data
				// is retrieved
				if ((contact.DisplayImage != null) && (contact.DisplayImage.ImageBuffer.Length == 0))
					return;
				
					SwitchContactImage (contact);
			}
		}
		
		void ContactPresenceChanged (object sender, EntityChangeEventArgs<IPresence> args)
		{
			GaduContact contact = args.Entity as GaduContact;
		
			_message_display.AddStatusChange (contact.DisplayIdentifier + " is now " + args.New.State);
			
			if (contact == Conversation.PrimaryContact && args.New == GaduPresence.Offline)
			{
				// We should disable several options 
			}
		}
		
		private void AccountDisplayImageChange (object sender, EventArgs args)
		{
			_own_image.FadeTo (GenerateOwnImage ());
		}
		
		private void ProcessIncomingMessage (IMessage message)
		{
			lock (_incomingMessages)
			{
				if (!_historyComplete)
				{
					Log.Debug ("Not showing, history is not complete.");
					_incomingMessages.Add (message);
					return;
				}
			}
			
			_message_display.AddMessage (message);
			
			_status_label.Text = "Last message received at: "+DateTime.Now.ToShortTimeString()+" - "+DateTime.Now.ToShortDateString();
			
			_activityImage.Pixbuf = IconUtility.GetIcon("galaxium-typing_anim");
			
			if (_window.CurrentWidget != this || !_window.Active)
				_window.GenerateAlert ();
			
			EmitBecomeActive ();
			
			SoundSetUtility.Play(Sound.MessageReceived);
		}
		
		private void ProcessOutgoingMessage (IMessage message)
		{
			// This is where we spawn to send the message in question.
			(_conversation as GaduConversation).SendMessage(message);
			
			SoundSetUtility.Play(Sound.MessageSent);
		}
		
		public void SendNudge ()
		{
			/*_conversation.SendNudge();
			
			(delegate () {
				if (Conversation.ContactCollection.Count == 1)
					_messageDisplay.AddSystemMessage ("You sent " + Conversation.PrimaryContact.DisplayIdentifier + " a nudge to get their attention!");
				else
					_messageDisplay.AddSystemMessage ("You sent a nudge!");
				
				if (_interfaceConfig.GetBool("WindowShake", true))
					_window.Shake ();
			});
			
			SoundSetUtility.Play(Sound.Nudge);*/
		}
		
		public void ToggleHistory (bool active)
		{
			//_historyBox.Visible = active;
			
			//if (!_notesBox.Visible)
				//_textBox.Visible = !active;
		}
		
		public void ToggleNotes (bool active)
		{
			//_notesBox.Visible = active;
			
			//if (!_historyBox.Visible)
				//_textBox.Visible = !active;
		}
		
		public void SendFile ()
		{
			/*FileChooserDialog dialog = new FileChooserDialog("Select File", null, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Select", ResponseType.Accept);
			dialog.SetCurrentFolder(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
			
			if (dialog.Run () == (int)ResponseType.Accept)
			{
				SendFile(dialog.Filename);
			}
			
			dialog.Destroy();*/
		}
		
		public override void SendFile (string filename)
		{
			/*if (Conversation.PrimaryContact == null)
			{
				Anculus.Core.Log.Warn ("There is no primary contact in this conversation to send files to!");
				return;
			}
			
			// Check to make sure that the file exists.
			if (File.Exists (filename))
			{
				GaduFileTransfer transfer = new GaduFileTransfer (Conversation.Session, Conversation.PrimaryContact, filename);
				
				GaduP2PUtility.Add (transfer.P2PTransfer);
				(Conversation.Session as GaduSession).EmitTransferInvitationSent (new FileTransferEventArgs (transfer));
			}
			else
			{
				string error = "The URI of the file you dropped is invalid!\n"+filename;
				MessageDialog errordialog = new MessageDialog (null, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, error);
				errordialog.Run ();
				errordialog.Destroy ();
			}*/
		}
		
		internal void ShowActivityPopup (Gtk.Widget position)
		{
			//HTMLPopup popup = new HTMLPopup (position, _conversation.ActivityPageUrl);
			//popup.ShowAll ();
		}
		
		void AdjustForContacts ()
		{
			if (_window.CurrentWidget == this)
				_window.GenerateTitle ();
			
			if (_conversation.ContactCollection.Count > 1)
			{
				ShowBox (ChatWidgetPositions.RightDisplayPane);
				HideBox (ChatWidgetPositions.RightInput);
				
				_window.Toolbar.ShowAll();
				_entryToolbar.ShowAll();
				
				ShowBox (ChatWidgetPositions.LeftInput);
				HideBox (ChatWidgetPositions.Identification);
			}
			else
			{
				HideBox (ChatWidgetPositions.RightDisplayPane);
				ShowBox (ChatWidgetPositions.RightInput);
				
				if (Conversation.PrimaryContact != null)
				{
					GaduContact contact = Conversation.PrimaryContact as GaduContact;
					
					if (contact.ShowActionToolbar)
						_window.Toolbar.ShowAll();
					else
						_window.Toolbar.Visible = false;
					
					if (contact.ShowInputToolbar)
						_entryToolbar.ShowAll();
					else
						_entryToolbar.Visible = false;
					
					if (contact.ShowAccountImage)
						ShowBox (ChatWidgetPositions.LeftInput);
					else
						HideBox (ChatWidgetPositions.LeftInput);
					
					if (contact.ShowContactImage)
						ShowBox (ChatWidgetPositions.RightInput);
					else
						HideBox (ChatWidgetPositions.RightInput);
					
					if (contact.ShowPersonalMessage)
						ShowBox (ChatWidgetPositions.Identification);
					else
						HideBox (ChatWidgetPositions.Identification);
					
					GeneratePersonalLabel();
					SwitchContactImage (contact);
				}
				else
				{
					Anculus.Core.Log.Error ("There is no primary contact for the conversation this chat widget represents!");
				}
			}
		}
		
		/*void ConversationMessageSendFailed (object sender, MessageEventArgs args)
		{
			_message_display.AddError (string.Format ("The message \"{0}\" could not be sent within a reasonable amount of time!", args.Message.Markup));
			EmitBecomeActive ();
		}*/
		
		/*void ConversationCapabilitiesChanged (object sender, EventArgs args)
		{
			if (_window.CurrentWidget == this)
			{
					MenuUtility.FillToolBar ("/Galaxium/Gui/GG/ContainerWindow/Toolbar", new DefaultExtensionContext (this), _window.Toolbar as Toolbar);
					MenuUtility.FillMenuBar ("/Galaxium/Gui/GG/ContainerWindow/Menu", new DefaultExtensionContext (this), _window.Menubar as MenuBar);
					MenuUtility.FillToolBar ("/Galaxium/Gui/GG/ContainerWindow/InputToolbar", new DefaultExtensionContext (this), _entryToolbar);
			}
		}*/
		
		protected override void OwnImageButtonPressEvent (object sender, ButtonPressEventArgs args)
		{
			//if (args.Event.Type == Gdk.EventType.TwoButtonPress)
				//new SetDisplayImageCommand().Run ();
		}
		
		public override void LoadFont ()
		{
		}
		
		public override void SaveFont ()
		{
		}
	}
}
